package conf

import (
	"../../deps/lessgo/data/redis"
	"../../deps/lessgo/utils"
	"errors"
	"fmt"
	"io/ioutil"
	"net"
	"os"
	"path/filepath"
	"regexp"
	"strings"
)

const (
	VERSION   = "0.3.0.dev"
	dbVersion = "db1"
)

var (
	StoreServerName = "lesskeeper-store"
	StoreServerPath = ""
	StoreServerArgs = ""
	Config          ConfigCommon
	StoreServerConf redis.Config
	LogPath         = ""
)

type ConfigCommon struct {
	HostId     string `json:"host_id"`
	Port       string `json:"port"`
	Prefix     string `json:"prefix"`
	KeeperAddr string `json:"keeper_addr"`
	KeeperPort string `json:"keeper_port"`
}

func Initialize(prefix string) error {

	var err error

	if prefix == "" {
		prefix, err = filepath.Abs(filepath.Dir(os.Args[0]) + "/..")
		if err != nil {
			prefix = "/opt/lesskeeper"
		}
	}
	reg, _ := regexp.Compile("/+")
	Config.Prefix = "/" + strings.Trim(reg.ReplaceAllString(prefix, "/"), "/")

	file := Config.Prefix + "/etc/keeper.json"
	if _, err := os.Stat(file); err != nil && os.IsNotExist(err) {
		return errors.New("Error: config file is not exists")
	}

	fp, err := os.Open(file)
	if err != nil {
		return errors.New(fmt.Sprintf("Error: Can not open (%s)", file))
	}
	defer fp.Close()

	cfgstr, err := ioutil.ReadAll(fp)
	if err != nil {
		return errors.New(fmt.Sprintf("Error: Can not read (%s)", file))
	}

	if err = utils.JsonDecode(cfgstr, &Config); err != nil {
		return errors.New(fmt.Sprintf("Error: "+
			"config file invalid. (%s)", err.Error()))
	}

	if len(Config.HostId) < 4 {
		return errors.New("host_id is not valid")
	}

	if len(Config.KeeperAddr) < 8 {
		// Fetch local ip address
		addrs, _ := net.InterfaceAddrs()
		reg, _ := regexp.Compile(`^(.*)\.(.*)\.(.*)\.(.*)\/(.*)$`)
		for _, addr := range addrs {
			ips := reg.FindStringSubmatch(addr.String())
			if len(ips) != 6 || (ips[1] == "127" && ips[2] == "0") {
				continue
			}
			Config.KeeperAddr = fmt.Sprintf("%s.%s.%s.%s", ips[1], ips[2], ips[3], ips[4])

		}
	}
	if len(Config.KeeperAddr) < 8 {
		Config.KeeperAddr = "127.0.0.1"
	}

	StoreServerPath = Config.Prefix + "/bin/" + StoreServerName
	if _, err := os.Stat(StoreServerPath); err != nil && os.IsNotExist(err) {
		return errors.New(fmt.Sprintf("Error: "+
			"lesskeeper-store (%s) is not exists", StoreServerPath))
	}
	StoreServerConf = redis.Config{
		Socket:  Config.Prefix + "/var/keeper.sock",
		Timeout: 3,
		MaxConn: 8,
	}
	StoreServerArgs = Config.Prefix + "/etc/redis.conf" +
		" --daemonize yes" +
		" --port 9526" +
		" --unixsocket " + StoreServerConf.Socket +
		" --dir " + Config.Prefix + "/var/" + dbVersion +
		" --dbfilename main.rdb"

	LogPath = Config.Prefix + "/var/keeper.log"

	return nil
}
